

//参数验证拦截器
import {Interceptor, InterceptorType} from "../../core/Interceptor";
import {ParaTypes} from "./EasyAParaTypes";
import {EasyACtx} from "../../core/EasyACtx";
import {Controller} from "../../core/Controller";
import {_} from "../../util/UtilTs";
import {Ctx} from "../../index";


export interface EasyACtxParaValidateInterceptor{
    validatedParams:any
}

export class ParaValidateInterceptor extends Interceptor{

    params = {};

    before(ctx: Ctx) {
        const params = this.params;

        ctx.validatedParams = {};

        for(let key in params){
            const pType = <ParaTypes>params[key];
            const ret = pType.doValidate(ctx,key,ctx.params[key]);
            if(ret === false){
                ctx.mm.code = -1;
                const lang =ctx.store.res;
                let definedErr = pType.errMsg;
                if(definedErr && definedErr.startsWith('@')){
                    let dd = definedErr.substr(1,definedErr.length);
                    definedErr = lang.res[dd];
                }

                ctx.mm.msg = definedErr ||  `参数错误:${key}应该输入${pType.name}类型`;
                ctx.isEnd = true;
                break;
            }
            else if (ret !== undefined){
                ctx.validatedParams[key] = ret;
            }
        }

        ctx.next()

    }

}


//参数验证 注解
export function ValidateParam(...params:Array<any>){

    let unionParams = {};

    _.forEach(params,(paramObject)=>{
        unionParams = _.assignIn(unionParams,paramObject)
    });

    return function (target,key) {
        const clazz = target.constructor;
        if(Controller.isControllerDClazz(target)){
            const clazzFunc = target[key];

            const inter = new ParaValidateInterceptor();
            inter.type = InterceptorType.flow;
            inter.params = unionParams;
            const inters = [inter];
            clazz.__init((ins)=>{
                const acName = clazzFunc.name;
                const oldInters = _.get(ins,`tempActionProps.${acName}.interceptors`,[]);
                _.set(ins, `tempActionProps.${acName}.interceptors`, inters.concat(oldInters)); //同样需要反着连接
            });
        }
        else {
            throw "方法必须写在controller 类里"
        }

    }
}